package equipments;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;

import equipments.enumeration.WeaponsType;


import systems.database.DataBaseHandler;
import systems.languages.MultiLanguages;
import tools.BonusAttribut;
import tools.Visitable;
import tools.Visitor;

public class Weapon implements Items,Visitable {

  private int id = 0;
  private String name;
  private int level;
  private int nbBonusAttr;
  private int nbManastone;
  private boolean hasDivineSlot;

  private int min_damage;
  private int max_damage;
  private double attack_speed;
  private int physical_crit;
  private int hit_accuracy;
  private int magic_accuracy;
  private int parry;
  private WeaponsType type;
  private boolean extendable;
  private LinkedList<BonusAttribut> bonusList;

  public Weapon(){
    this.nbBonusAttr = 0;
    this.setBonusList(new LinkedList<BonusAttribut>());
  }
  
  @Override
  public void init(String id) {
    this.id = Integer.valueOf(id);
    initItem(DataBaseHandler.getStatement());
  }
  public int getID()
  {
    return this.id;
  }

  @Override
  public int getLevel() {
    return this.level;
  }

  @Override
  public String getName() {
    return this.name;
  }

  @Override
  public int getNbBonusAttr() {
    return this.nbBonusAttr;
  }

  @Override
  public int getNbManastone() {
    return this.nbManastone;
  }

  @Override
  public boolean hasDivineSlot() {
    return this.hasDivineSlot;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void setLevel(int level) {
    this.level = level;
  }

  public void setNbBonusAttr(int nbBonusAttr) {
    this.nbBonusAttr = nbBonusAttr;
  }

  public void setNbManastone(int nbManastone) {
    this.nbManastone = nbManastone;
  }

  public void setHasDivineSlot(boolean hasDivineSlot) {
    this.hasDivineSlot = hasDivineSlot;
  }

  public boolean isHasDivineSlot() {
    return hasDivineSlot;
  }

  public void setMin_damage(int min_damage) {
    this.min_damage = min_damage;
  }

  public int getMin_damage() {
    return min_damage;
  }

  public void setMax_damage(int max_damage) {
    this.max_damage = max_damage;
  }

  public int getMax_damage() {
    return max_damage;
  }

  public void setAttack_speed(double attack_speed) {
    this.attack_speed = attack_speed;
  }

  public double getAttack_speed() {
    return attack_speed;
  }

  public void setPhysical_crit(int physical_crit) {
    this.physical_crit = physical_crit;
  }

  public int getPhysical_crit() {
    return physical_crit;
  }

  public void setHit_accuracy(int hit_accuracy) {
    this.hit_accuracy = hit_accuracy;
  }

  public int getHit_accuracy() {
    return hit_accuracy;
  }

  public void setMagic_accuracy(int magic_accuracy) {
    this.magic_accuracy = magic_accuracy;
  }

  public int getMagic_accuracy() {
    return magic_accuracy;
  }

  public void setParry(int parry) {
    this.parry = parry;
  }

  public int getParry() {
    return parry;
  }

  @Override
  public void initItem(Statement transmission) {
    ResultSet resultat;
    this.setBonusList(new LinkedList<BonusAttribut>());
    try {
      //Starting with getting the name ...
      resultat= transmission.executeQuery("SELECT body FROM "
          +MultiLanguages.getProperties("database.Language.name")
          +" where oid = "+this.id);
      while(resultat.next())
        this.name=resultat.getString("body");

      //Recuperation des stats des initialisation
      resultat = transmission.executeQuery("Select * from items where id="+id);
      while(resultat.next())
      {
        int cpt=1;
        while(cpt<13)
        {
          if(resultat.getString("bonus_attr"+cpt)!=null)
          {     
        	  this.getBonusList().add(new BonusAttribut(resultat.getString("bonus_attr"+cpt)));
        	  this.nbBonusAttr++;
   		  }
          cpt++;
        }
        //J'ai pas réussi a trouver d'arme qui n'avait pas de divine slot...
        this.hasDivineSlot=true;

        this.level = resultat.getInt("level");

        this.min_damage=resultat.getInt("min_damage");
        this.max_damage=resultat.getInt("max_damage");
        this.hit_accuracy=resultat.getInt("hit_accuracy");
        this.parry=resultat.getInt("parry");
        this.magic_accuracy=resultat.getInt("magical_hit_accuracy");
        this.attack_speed=resultat.getDouble("attack_delay")/1000;
        this.physical_crit=resultat.getInt("critical");
        this.nbManastone=resultat.getInt("slots");

        if(resultat.getInt("attack_range")==4 ||resultat.getInt("attack_range") ==6)
          this.extendable=true;
        else
          this.extendable=false;
/*
        if(this.nbBonusAttr!=0)
        {
          for(int i=1;i<this.nbBonusAttr+1;i++)
          {    
        	  this.getBonusList().add(new BonusAttribut(resultat.getString("bonus_attr"+i)));
          }
        }*/
        String type = resultat.getString("weapon_type");
        switch(type.charAt(0))
        {
          case '1': type = type.replaceFirst("1", "one_");break;
          case '2': type = type.replaceFirst("2", "two_");break;
        }
        this.type = WeaponsType.valueOf(type);
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

  public void setExtendable(boolean extendable) {
    this.extendable = extendable;
  }

  public boolean isExtendable() {
    return extendable;
  }

  public String toString()
  {
    String bonus="";
    for(int i=0;i<this.getBonusList().size();i++)
    {
      bonus+="\nBonus "+i+": "+this.getBonusList().get(i).toString();
    }

    return "Name :"+ this.name+
    "\nlevel: "+this.level+
    "\nmin_damage: "+this.min_damage+
    "\nmax_damage: "+this.max_damage+
    "\nManastone slot: "+this.nbManastone+
    "\nGodstone slot: "+this.hasDivineSlot+
    "\nAttack_speed: "+this.attack_speed+
    "\nPhysical_crit: "+this.physical_crit+
    "\nHit_accuracy: "+this.hit_accuracy+
    "\nmagic_accuracy: "+this.magic_accuracy+
    "\nParry: "+this.parry+
    "\nExtendable: "+this.extendable+
    bonus;
  }

  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }

  public void setBonusList(LinkedList<BonusAttribut> bonusList) {
    this.bonusList = bonusList;
  }

  public LinkedList<BonusAttribut> getBonusList() {
    return bonusList;
  }

  public void setType(WeaponsType newType) {
    this.type = newType;
  }

  public WeaponsType getType() {
    return this.type;
  }

  public boolean isTwoHand()
  {
    return this.type.isTwoHand();
  }
  
  public void updateName() {
    ResultSet resultat;
    try {
      resultat= DataBaseHandler.getStatement().executeQuery("SELECT body FROM "
          +MultiLanguages.getProperties("database.Language.name")
          +" where oid = "+this.id);
      while(resultat.next())
        this.name=resultat.getString("body");  
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

@Override
public void acceptBonusRemoval(Visitor visitor) {
	visitor.bonusvisit(this);		
}
}
